package com.wisemoresystem.seal.util.abchinaFinger.cics;

import java.util.Vector;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.ibm.ctg.client.ECIRequest;
import com.ibm.ctg.client.JavaGateway;
import com.wisemoresystem.seal.util.abchinaFinger.common.AbcCoreCfg;
import com.wisemoresystem.seal.util.abchinaFinger.common.CodeUtil;

public class CicsTrans {
	private static Log log = LogFactory.getLog(CicsTrans.class);
	static final String DEFAULTCHARSET = "GBK";

	private static final int MAX_APPL_SIZE = 4096;
	private static final short TIME_OUT_SECONDS = 60;
	private static JavaGateway jgateway;

	private AbcCoreCfg abcConfig;

	/**
	 * @param cicsConfig
	 */
	public CicsTrans(AbcCoreCfg abcConfig) {
		this.abcConfig = abcConfig;
	}

	/**
	 * @throws Exception
	 */
	public void openGateway() throws Exception {
		log.debug("CicsTran:open GateWay！");
		// 创建jgateway
		if (jgateway == null) {
			jgateway = new JavaGateway();
		}

		// 打开jgateway
		if (jgateway.isOpen()) {
			return;
		}

		log.debug("CicsTrans: create gateway:" + abcConfig.toString());

		try {
			jgateway.setURL(abcConfig.getServer().trim());
			jgateway.setPort(Integer.parseInt(abcConfig.getPort().trim()));
			jgateway.open();
		} catch (Exception e) {
			jgateway.close();
			log.error("CicsTrans:open gateway Failed !");
			throw new Exception("CicsTrans:open gateway Failed ,Reason:("
					+ e.getMessage() + ")");
		}
		log.debug("CicsTrans:open gateway Success !");
	}

	/**
	 * 关闭Java Gateway
	 * 
	 * @throws Exception
	 *             抛出异常
	 */
	public void closeGateway() throws Exception {
		log.debug("CicsTrans:close gateway");
		if ((jgateway != null) && (jgateway.isOpen())) {
			jgateway.close();
		}

		log.debug("CicsTrans:close gateway SUCCESS !");
	}

	/**
	 * 销毁jgateway
	 * 
	 * @throws Exception
	 *             抛出异常
	 */
	public void dispose() throws Exception {
		jgateway = null;
	}

	/**
	 * 调用Cics ECI请求获取服务返回信息
	 * 
	 * @param commarea
	 *            请求报文内容
	 * @param commareasize
	 *            报文大小
	 * @param type
	 *            认证类型
	 * @return 返回服务端回应字节流
	 */
	public byte[] runECICall(String commarea, int commareasize, String type)
			throws Exception {
		String status = "CicsTrans : EciCall:";
		log.debug(status);

		// 检测报文是否为空
		if ((commarea == null) || (commarea.equals(""))) {
			status = "CicsTrans EciCall:请求报文不可为空!";
			log.error(status);
			throw new Exception(status);
		}

		if ((jgateway == null) || (!jgateway.isOpen())) {
			this.openGateway();
		}

		// 检测ECIRequest的列表是否为空
		ECIRequest ecireq = ECIRequest.listSystems(40);
		int rc = jgateway.flow(ecireq);
		checkReturnCode(rc, ecireq);
		if (ecireq.SystemList.isEmpty()) {
			closeGateway();
			status = "CicsTran EciCall: 找不到对应服务，请检查CTG服务进程！";
			log.error(status);
			throw new Exception(status);
		}

		// 检测指定的服务名
		@SuppressWarnings("rawtypes")
		Vector servers = ecireq.SystemList;
		boolean validserver = false;
		if ((ecireq.numServersReturned > 0) && (servers != null)) {
			for (int i = 0; i < servers.size(); i++) {
				if (!servers.elementAt(i).equals(abcConfig.getServicename()))
					continue;
				validserver = true;
				status = "CicsTran EciCall: 找到Services :"
						+ abcConfig.getServicename();
				log.debug(status);
				break;
			}
		}

		if (!validserver) {
			status = "CicsTran EciCall: 找不到对应的Services,请检查CTG配置："
					+ abcConfig.getServicename();
			log.error(status);
			throw new Exception(status);
		}

		commareasize = MAX_APPL_SIZE;
		byte[] incommarea = new byte[commareasize];
		System.arraycopy(commarea.getBytes(), 0, incommarea, 0,
				Math.min(incommarea.length, commarea.getBytes().length));
		if ("1".equals(type)) {
			incommarea = CodeUtil.ASCIIToEBCDIC(incommarea);
		}

		// 创建ECIRequest
		ecireq = new ECIRequest(ECIRequest.ECI_SYNC, abcConfig.getServicename()
				.trim(), abcConfig.getUser().trim(),
				abcConfig.getPass().trim(), abcConfig.getProgram().trim(),
				abcConfig.getTranid().trim(), incommarea, incommarea.length,
				ECIRequest.ECI_NO_EXTEND, 0);
		ecireq.setECITimeout(TIME_OUT_SECONDS);
		log.debug("CicsTrans EciCall:  Create ECIRequest ！");

		// 执行jgateway.flow
		rc = jgateway.flow(ecireq);
		log.debug("CicsTrans EciCall: jgateway.flow！");

		checkReturnCode(rc, ecireq);
		log.debug("CicsTrans EciCall: checkReturnCode !");

		log.debug("CicsTrans EciCall: 调用EciCall完成！");
		// return incommarea;
		return ecireq.Commarea;
	}

	/**
	 * 调用Cics ECI请求获取服务返回信息
	 * 
	 * @param commarea
	 *            请求报文内容
	 * @param type
	 *            认证类型 0-指纹 1-密码
	 * @return 返回服务端回应字节流
	 */
	public byte[] runECICall(String commarea, String type) throws Exception {
		return runECICall(commarea, commarea.getBytes(DEFAULTCHARSET).length,
				type);
	}

	/**
	 * 检测EciRequest执行返回码
	 * 
	 * @param returncode
	 *            返回代码
	 * @param eci
	 *            ECI Request
	 * @throws Exception
	 *             抛出异常
	 */
	private void checkReturnCode(int returncode, ECIRequest eci)
			throws Exception {
		if (returncode != 0) {
			if (eci.getCicsRc() == 0) {
				throw new Exception(
						"CicsTran EX:Gateway exception: Return code number:"
								+ returncode + " Return code String: "
								+ eci.getRcString());
			}

			if ((eci.getCicsRc() == -27)
					|| ((eci.Abend_Code != null) && (eci.Abend_Code
							.equalsIgnoreCase("AEY7")))) {
				throw new Exception(
						"CicsTran EX:Server is unable to validate UserId or password");
			}

			throw new Exception(
					"CicsTran EX:CICS exception: Return code number:"
							+ returncode + " Return code String: "
							+ eci.getCicsRcString());
		}
	}

}
